package com.stx.jeepay.payment.service;

import com.alibaba.fastjson.JSONObject;
import com.stx.jeepay.core.entity.MchNotifyRecordEntity;
import com.stx.jeepay.core.entity.PayOrderEntity;
import com.stx.jeepay.core.entity.RefundOrderEntity;
import com.stx.jeepay.core.entity.TransferOrderEntity;
import com.stx.jeepay.core.expection.BizException;
import com.stx.jeepay.core.mq.model.PayOrderMchNotifyMQ;
import com.stx.jeepay.core.mq.vender.IMQSender;
import com.stx.jeepay.core.service.MchNotifyRecordService;
import com.stx.jeepay.core.utils.JeepayKit;
import com.stx.jeepay.core.utils.StringKit;
import com.stx.jeepay.payment.rqrs.QueryPayOrderRS;
import com.stx.jeepay.payment.rqrs.refund.QueryRefundOrderRS;
import com.stx.jeepay.payment.rqrs.transfer.QueryTransferOrderRS;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class PayMchNotifyService {

    @Autowired
    private MchNotifyRecordService mchNotifyRecordService;

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Autowired
    private IMQSender mqSender;

    /**
     * 商户通知信息， 只有订单是终态，才会发送通知， 如明确成功和明确失败
     **/
    public void payOrderNotify(PayOrderEntity dbPayOrder) {
        try {
            if (StringUtils.isEmpty(dbPayOrder.getNotifyUrl())) {
                // 如果通知地址为空
                return;
            }

            //获取到通知对象
            MchNotifyRecordEntity mchNotifyRecord = mchNotifyRecordService.findByPayOrder(dbPayOrder.getPayOrderId());
            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }
            //商户app私钥
            String appSecret = configContextQueryService.queryMchApp(dbPayOrder.getMchNo(), dbPayOrder.getAppId()).getAppSecret();

            // 封装通知url
            String notifyUrl = createNotifyUrl(dbPayOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecordEntity();
            mchNotifyRecord.setOrderId(dbPayOrder.getPayOrderId());
            mchNotifyRecord.setOrderType(MchNotifyRecordEntity.TYPE_PAY_ORDER);
            mchNotifyRecord.setMchNo(dbPayOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbPayOrder.getMchOrderNo());
            mchNotifyRecord.setIsvNo(dbPayOrder.getIsvNo());
            mchNotifyRecord.setAppId(dbPayOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecordEntity.STATE_ING); // 通知中

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));
        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

    /**
     * 创建响应URL
     */
    public String createNotifyUrl(PayOrderEntity payOrder, String appSecret) {
        QueryPayOrderRS queryPayOrderRS = QueryPayOrderRS.buildByPayOrder(payOrder);
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(queryPayOrderRS);
        jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(payOrder.getNotifyUrl(), jsonObject);
    }

    /**
     * 创建响应URL
     */
    public String createReturnUrl(PayOrderEntity payOrder, String appSecret) {
        if (StringUtils.isEmpty(payOrder.getReturnUrl())) {
            return "";
        }

        QueryPayOrderRS queryPayOrderRS = QueryPayOrderRS.buildByPayOrder(payOrder);
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(queryPayOrderRS);
        jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));   // 签名

        // 生成跳转地址
        return StringKit.appendUrlQuery(payOrder.getReturnUrl(), jsonObject);
    }

    /**
     * 商户通知信息，退款成功的发送通知
     **/
    public void refundOrderNotify(RefundOrderEntity dbRefundOrder) {
        try {
            // 通知地址为空
            if (StringUtils.isEmpty(dbRefundOrder.getNotifyUrl())) {
                return;
            }

            //获取到通知对象
            MchNotifyRecordEntity mchNotifyRecord =
                    mchNotifyRecordService.findByRefundOrder(dbRefundOrder.getRefundOrderId());

            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }

            //商户app私钥
            String appSecret =
                    configContextQueryService.queryMchApp(dbRefundOrder.getMchNo(), dbRefundOrder.getAppId()).getAppSecret();

            // 封装通知url
            String notifyUrl = createNotifyUrl(dbRefundOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecordEntity();
            mchNotifyRecord.setOrderId(dbRefundOrder.getRefundOrderId());
            mchNotifyRecord.setOrderType(MchNotifyRecordEntity.TYPE_REFUND_ORDER);
            mchNotifyRecord.setMchNo(dbRefundOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbRefundOrder.getMchRefundNo()); //商户订单号
            mchNotifyRecord.setIsvNo(dbRefundOrder.getIsvNo());
            mchNotifyRecord.setAppId(dbRefundOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecordEntity.STATE_ING); // 通知中
            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));
        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

    /**
     * 创建响应URL
     */
    public String createNotifyUrl(RefundOrderEntity refundOrder, String appSecret) {

        QueryRefundOrderRS queryRefundOrderRS = QueryRefundOrderRS.buildByRefundOrder(refundOrder);
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(queryRefundOrderRS);
        jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(refundOrder.getNotifyUrl(), jsonObject);
    }

    /**
     * 商户通知信息，转账订单的通知接口
     **/
    public void transferOrderNotify(TransferOrderEntity dbTransferOrder) {
        try {
            // 通知地址为空
            if (StringUtils.isEmpty(dbTransferOrder.getNotifyUrl())) {
                return;
            }

            // 获取通知对象
            MchNotifyRecordEntity mchNotifyRecord =
                    mchNotifyRecordService.findByTransferOrder(dbTransferOrder.getTransferId());

            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }

            // 商户App私钥
            String appSecret =
                    configContextQueryService.queryMchApp(dbTransferOrder.getMchNo(), dbTransferOrder.getAppId()).getAppSecret();

            // 封装url通知

            String notifyUrl = createNotifyUrl(dbTransferOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecordEntity();
            mchNotifyRecord.setOrderId(dbTransferOrder.getTransferId());
            mchNotifyRecord.setOrderType(MchNotifyRecordEntity.TYPE_TRANSFER_ORDER);
            mchNotifyRecord.setMchNo(dbTransferOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbTransferOrder.getMchOrderNo());
            mchNotifyRecord.setIsvNo(dbTransferOrder.getIsvNo());
            mchNotifyRecord.setAppId(dbTransferOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecordEntity.STATE_ING);


            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            // MQ通知
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));
        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

    /**
     * 创建响应URL
     */
    public String createNotifyUrl(TransferOrderEntity transferOrder, String appSecret) {

        QueryTransferOrderRS rs = QueryTransferOrderRS.buildByRecord(transferOrder);
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(rs);
        jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(transferOrder.getNotifyUrl(), jsonObject);
    }
}
